package jannex.internal;

import jannex.JannexException;
import jannex.label.LabelMap;
import jannex.sql.JxResultSetMetaData;
import jannex.sql.JxSqlFeatureNotSupportedException;

import java.sql.ResultSetMetaData;
import java.util.Map;

public class ResultRowMetaData implements JxResultSetMetaData {

    private final String[] labels;
    private final String[] tables;
    private final ResultRow result;

    private final Map<String, Integer> index;

    public ResultRowMetaData(ResultRow result, String[] labels, String[] tables) {
        this.result = result;
        this.labels = labels;
        this.tables = tables;
        LabelMap.Builder<Integer> builder = LabelMap.builder(labels.length);
        for (int i = 0; i < labels.length; i++) {
            builder.put(labels[i], i + 1);
        }
        this.index = builder.build();
    }

    @Override
    public boolean isAutoIncrement(String columnLabel) {
        return isAutoIncrement(getColumn(columnLabel));
    }

    @Override
    public boolean isSearchable(String columnLabel) {
        return isSearchable(getColumn(columnLabel));
    }

    @Override
    public boolean isCurrency(String columnLabel) {
        return isCurrency(getColumn(columnLabel));
    }

    @Override
    public int isNullable(String columnLabel) {
        return isNullable(getColumn(columnLabel));
    }

    @Override
    public boolean isSigned(String columnLabel) {
        return isSigned(getColumn(columnLabel));
    }

    @Override
    public int getColumnDisplaySize(String columnLabel) {
        return getColumnDisplaySize(getColumn(columnLabel));
    }

    @Override
    public String getColumnName(String columnLabel) {
        return getColumnName(getColumn(columnLabel));
    }

    @Override
    public String getSchemaName(String columnLabel) {
        return getSchemaName(getColumn(columnLabel));
    }

    @Override
    public int getPrecision(String columnLabel) {
        return getPrecision(getColumn(columnLabel));
    }

    @Override
    public int getScale(String columnLabel) {
        return getScale(getColumn(columnLabel));
    }

    @Override
    public String getTableName(String columnLabel) {
        return getTableName(getColumn(columnLabel));
    }

    @Override
    public String getCatalogName(String columnLabel) {
        return getCatalogName(getColumn(columnLabel));
    }

    @Override
    public int getColumnType(String columnLabel) {
        return getColumnType(getColumn(columnLabel));
    }

    @Override
    public String getColumnTypeName(String columnLabel) {
        return getColumnTypeName(getColumn(columnLabel));
    }

    @Override
    public boolean isReadOnly(String columnLabel) {
        return isReadOnly(getColumn(columnLabel));
    }

    @Override
    public boolean isWritable(String columnLabel) {
        return isWritable(getColumn(columnLabel));
    }

    @Override
    public boolean isDefinitelyWritable(String columnLabel) {
        return isDefinitelyWritable(getColumn(columnLabel));
    }

    @Override
    public String getColumnClassName(String columnLabel) {
        return getColumnClassName(getColumn(columnLabel));
    }

    @Override
    public int getColumn(String columnLabel) throws JannexException {
        return index.get(columnLabel);
    }

    @Override
    public boolean containsColumnLabel(String columnLabel) throws JannexException {
        return index.containsKey(columnLabel);
    }

    @Override
    public String[] getColumnLabels() throws JannexException {
        return labels;
    }

    @Override
    public Map<String, Integer> getColumnLabelMap() throws JannexException {
        return index;
    }

    @Override
    public int getColumnCount() throws JannexException {
        return labels.length;
    }

    @Override
    public boolean isAutoIncrement(int column) throws JannexException {
        return false;
    }

    @Override
    public boolean isCaseSensitive(int column) throws JannexException {
        return false;
    }

    @Override
    public boolean isSearchable(int column) throws JannexException {
        return false;
    }

    @Override
    public boolean isCurrency(int column) throws JannexException {
        return false;
    }

    @Override
    public int isNullable(int column) throws JannexException {
        return ResultSetMetaData.columnNullableUnknown;
    }

    @Override
    public boolean isSigned(int column) throws JannexException {
        return false;
    }

    @Override
    public int getColumnDisplaySize(int column) throws JannexException {
        return 0;
    }

    @Override
    public String getColumnLabel(int column) throws JannexException {
        return labels[column - 1];
    }

    @Override
    public String getColumnName(int column) throws JannexException {
        return getColumnLabel(column);
    }

    @Override
    public String getSchemaName(int column) throws JannexException {
        return "";
    }

    @Override
    public int getPrecision(int column) throws JannexException {
        return 0;
    }

    @Override
    public int getScale(int column) throws JannexException {
        return 0;
    }

    @Override
    public String getTableName(int column) throws JannexException {
        return tables[column - 1];
    }

    @Override
    public String getCatalogName(int column) throws JannexException {
        return "";
    }

    @Override
    public int getColumnType(int column) throws JannexException {
        return SqlTypeUtils.sqlTypeOf(result.getObject(column).getClass());
    }

    @Override
    public String getColumnTypeName(int column) throws JannexException {
        return SqlTypeUtils.nameOfType(result.getObject(column).getClass());
    }

    @Override
    public boolean isReadOnly(int column) throws JannexException {
        return false;
    }

    @Override
    public boolean isWritable(int column) throws JannexException {
        return false;
    }

    @Override
    public boolean isDefinitelyWritable(int column) throws JannexException {
        return false;
    }

    @Override
    public String getColumnClassName(int column) throws JannexException {
        return result.getObject(column).getClass().getName();
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws JannexException {
        throw new JxSqlFeatureNotSupportedException("Cannot unwrap ResultRowMetaData");
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws JannexException {
        return false;
    }
}
